//
//  ViewController.m
//  蓝牙2代解析
//
//  Created by HYZ on 16/4/19.
//  Copyright © 2016年 HYZ. All rights reserved.
//

#import "ViewController.h"
#import "BabyBluetooth.h"
typedef NS_ENUM(int, modeltyep){
        tyepaction  = 1,//次数数据
        tyeptime   = 2,//时间数据
        tyepangle  = 3//角度数据
    
};
@interface ViewController ()<UITableViewDelegate,UITableViewDataSource>
@property (weak, nonatomic) IBOutlet UITableView *blueToothTableView;
@property (weak, nonatomic) IBOutlet UILabel *action;
@property (weak, nonatomic) IBOutlet UILabel *speed;
@property (weak, nonatomic) IBOutlet UILabel *sync_flag;
@property (weak, nonatomic) IBOutlet UILabel *index;
@property (weak, nonatomic) IBOutlet UILabel *power;
@property (weak, nonatomic) IBOutlet UILabel *year;
@property (weak, nonatomic) IBOutlet UILabel *month;
@property (weak, nonatomic) IBOutlet UILabel *day;
@property (weak, nonatomic) IBOutlet UILabel *hour;
@property (weak, nonatomic) IBOutlet UILabel *min;
@property (weak, nonatomic) IBOutlet UILabel *sec;
/**角度 */
@property (weak, nonatomic) IBOutlet UILabel *angle;
/**角度方向 */
@property (weak, nonatomic) IBOutlet UILabel *angle_direction;
/**局值 */
@property (weak, nonatomic) IBOutlet UILabel *inning_val;
/**垂直的角度 */
@property (weak, nonatomic) IBOutlet UILabel *vertical_angle;
/**垂直角度的方向 */
@property (weak, nonatomic) IBOutlet UILabel *vertical_angle_direction;
/**设备ID */
@property (weak, nonatomic) IBOutlet UILabel *typeid;
/**别名 */
@property (weak, nonatomic) IBOutlet UITextField *nameText;





//搜索到的蓝牙设备数组
@property(strong,nonatomic) NSMutableArray<NSString*> * blueItems;
@property(strong,nonatomic) NSString * bluename;

@property(strong,nonatomic) BabyBluetooth * baby;
@property(strong,nonatomic) NSMutableArray<CBPeripheral*> * currPeripherals;
@property(strong,nonatomic) CBPeripheral * mainperipheral;
//订阅数据特征
@property(strong,nonatomic) CBCharacteristic * dataCharacteristic;

@end

@implementation ViewController

-(NSMutableArray *)blueItems{
    if (!_blueItems) {
        _blueItems = [NSMutableArray array];
       
    }
    return _blueItems;
}
-(NSMutableArray<CBPeripheral *> *)currPeripherals
{
    if (!_currPeripherals) {
        _currPeripherals = [NSMutableArray array];
    }
    return _currPeripherals;
}
- (void)viewDidLoad {
    [super viewDidLoad];
    self.baby = [BabyBluetooth shareBabyBluetooth];
    //设置代理
    [self babyDelegate];
    //设置委托后直接可以使用，无需等待CBCentralManagerStatePoweredOn状态
    self.baby.scanForPeripherals().begin();
    
}

-(void)babyDelegate{
    //设置扫描到设备的委托
    __block typeof(self) weakSelf = self;
    [self.baby setBlockOnDiscoverToPeripherals:^(CBCentralManager *central, CBPeripheral *peripheral, NSDictionary *advertisementData, NSNumber *RSSI) {
        NSLog(@"搜索到了设备:%@-----UUID:%@",peripheral.name,peripheral.identifier.UUIDString);
        
        if (self.bluename != peripheral.name) {
            [weakSelf.blueItems addObject:peripheral.name];
            [weakSelf.currPeripherals addObject:peripheral];
        }
        weakSelf.bluename = peripheral.name;
        [weakSelf.blueToothTableView reloadData];
    }];
    
    //过滤器
    //设置查找设备的过滤器
    [self.baby setFilterOnDiscoverPeripherals:^BOOL(NSString *peripheralName, NSDictionary *advertisementData, NSNumber *RSSI) {
        //最常用的场景是查找某一个前缀开头的设备
        //if ([peripheralName hasPrefix:@"Pxxxx"] ) {
        //    return YES;
        //}
        //return NO;
        //设置查找规则是名称大于1 ， the search rule is peripheral.name length > 1
        if (peripheralName.length >1) {
            return YES;
        }
        return NO;
    }];
    //搜索设备
    self.baby.scanForPeripherals().begin();
    
    //搜索设备10秒后停止
    self.baby.scanForPeripherals().begin().stop(10);
    
    //设置设备连接成功的委托,同一个baby对象，使用不同的channel切换委托回调
    [self.baby setBlockOnConnected:^(CBCentralManager *central, CBPeripheral *peripheral) {
        NSLog(@"设备：%@--连接成功",peripheral.name);
        
        
    }];
    
    
    //设置发现设service的Characteristics(特征)的委托 判断charact的UUID来确定服务通道
    [self.baby setBlockOnDiscoverCharacteristics:^(CBPeripheral *peripheral, CBService *service, NSError *error) {
//        NSLog(@"===service name:%@",service.UUID);
        for (CBCharacteristic * charact  in service.characteristics) {
            if ([charact.UUID.UUIDString isEqualToString: @"FFE9"]) {
                weakSelf.dataCharacteristic = charact;
                //连接成功之后给蓝牙发送获取设备信息命令,用来判断设备的类型
                NSData * data =[weakSelf setupdata:nil fororder:1];
                [weakSelf.mainperipheral writeValue:data forCharacteristic:weakSelf.dataCharacteristic type:CBCharacteristicWriteWithResponse];
            }else{
                 NSLog(@"%@---%@",peripheral,charact);
//                订阅通知
                [weakSelf.baby notify:peripheral characteristic:charact block:^(CBPeripheral *peripheral, CBCharacteristic *character, NSError *error) {
                    //接收到数据
//                    NSLog(@"接收到数据character  = %@ ",character);
                    NSLog(@"%@---%@",peripheral,character);
                    if (charact.value) {
                        //处理数据
                        [weakSelf proceData:charact.value];
                    }
                    
                }];
            }
            
        }
        
        
        
    }];
    
    
    //设置设备连接失败的委托
    [self.baby setBlockOnFailToConnect:^(CBCentralManager *central, CBPeripheral *peripheral, NSError *error) {
        NSLog(@"设备：%@--连接失败",peripheral.name);
    }];
    
    //设置设备断开连接的委托
    [self.baby setBlockOnDisconnect:^(CBCentralManager *central, CBPeripheral *peripheral, NSError *error) {
        NSLog(@"设备：%@--断开连接",peripheral.name);
    }];
    

}
#pragma mark -设置蓝牙别名命令
- (IBAction)getDiInFo:(id)sender {
    NSData * data = [self setupdata:self.nameText.text fororder:56];
   
    [self.mainperipheral writeValue:data forCharacteristic:self.dataCharacteristic type:CBCharacteristicWriteWithResponse];
}
#pragma mark -接收实时数据命令
- (IBAction)Realdata:(id)sender {
    
//    NSString * i = @"33";
//    NSData* data = [i dataUsingEncoding:NSUTF8StringEncoding];
    NSData * data =[self setupdata:nil fororder:33];
    
    [self.mainperipheral writeValue:data forCharacteristic:self.dataCharacteristic type:CBCharacteristicWriteWithResponse];
}
#pragma mark -关闭接收实时数据命令
- (IBAction)stopRealdata:(id)sender {

   NSData * data =[self setupdata:nil fororder:34];

    [self.mainperipheral writeValue:data forCharacteristic:self.dataCharacteristic type:CBCharacteristicWriteWithResponse];
}
#pragma mark -获取设备命令
- (IBAction)sendBluedata:(id)sender {
   NSData * data =[self setupdata:nil fororder:1];
    [self.mainperipheral writeValue:data forCharacteristic:self.dataCharacteristic type:CBCharacteristicWriteWithResponse];
}
#pragma mark -断开蓝牙连接
- (IBAction)disconnect:(id)sender {
    [self.baby cancelPeripheralConnection:self.mainperipheral];
}

#pragma mark - 处理数据 value : 为蓝牙传送过来的数据
-(void)proceData:(NSData *)value{
   NSString* str =  [self hexStringFromString:value];
    //字节数组
    Byte *testByte = (Byte *)[value bytes];
    //和用来验证CRC
    int index = 0;
    //CRC
    int crc = 0 ;
//    NSLog(@"testByte==%s",testByte);
    for(int i=0;i<([value length]);i++){
        if (i == ([value length] -2)) {
            crc = testByte[i];
//            NSLog(@"crc = %d",crc);
            continue;
        }
//        NSLog(@"%d",testByte[i]);
         index += testByte[i];
        
    }
//    NSLog(@"index==%d",index);
//    NSLog(@"str === %@",str);
    //验证CRC 信息是否正确
    if (index % 256 == crc) {
        if ([[str substringWithRange:NSMakeRange(0, 2)] isEqualToString:@"01"]) {//设备信息的数据,通过设备ID来判断设备的类型
            NSString * typeidstr = [str substringWithRange:NSMakeRange(6, 2)];
            NSString * U8typeidstr = [self getBinaryByhex:typeidstr];
            int typeid = (int)strtoul([U8typeidstr UTF8String], 0, 2);
            self.typeid.text = [NSString stringWithFormat:@"设备ID %d",typeid];
            
        }else if ([[str substringWithRange:NSMakeRange(0, 2)] isEqualToString:@"03"]){//用户信息的数据
            
            
            
            
        }else if ([[str substringWithRange:NSMakeRange(0, 2)] isEqualToString:@"21"]){//实时获取的数据
            
            NSString * actionstr = [str substringWithRange:NSMakeRange(4, 4)];//次数U16
            NSString * newactionstr = [self handleStringU16:actionstr];
            NSString * U16actionstr = [self getBinaryByhex:newactionstr];
            [self dealData:U16actionstr fortyep:tyepaction];//处理数据显示UI
//            NSLog(@"U16actionstr==%@",U16actionstr);
            
            NSString * indexstr = [str substringWithRange:NSMakeRange(8, 4)];//索引U16
            NSString * newindexstr = [self handleStringU16:indexstr];
            NSString * U16indexstr = [self getBinaryByhex:newindexstr];
            int index = (int) strtoul([U16indexstr UTF8String], 0, 2);//转为10进制
            //第几拍
            self.index.text = [NSString stringWithFormat:@"第 %d 拍",index];
//            NSLog(@"U16indexstr==%@",U16indexstr);
            
            NSString * timestr = [str substringWithRange:NSMakeRange(12, 8)];//时间U32
            NSString * newtimestr = [self handleStringU32:timestr];
            NSString * U32timestr = [self getBinaryByhex:newtimestr];

            [self dealData:U32timestr fortyep:tyeptime];
//            NSLog(@"U32timestr==%@",U32timestr);
            
            
            NSString * powerstr = [str substringWithRange:NSMakeRange(20, 4)];//力量U16
            NSString * newpowerstr = [self handleStringU16:powerstr];
            NSString * U16powerstr = [self getBinaryByhex:newpowerstr];
            int power = (int) strtoul([U16powerstr UTF8String], 0, 2);//转为10进制
            //力量
            self.power.text = [NSString stringWithFormat:@"力量 %d",power];
//            NSLog(@"U16powerstr==%@",U16powerstr);
            
            
            NSString * anglestr = [str substringWithRange:NSMakeRange(24, 8)];//角度U32
            NSString * newanglestr = [self handleStringU32:anglestr];
            NSString * U32anglestr = [self getBinaryByhex:newanglestr];
//            NSLog(@"newanglestr==%@",newanglestr);
//            NSLog(@"U32anglestr==%@",U32anglestr);

            [self dealData:U32anglestr fortyep:tyepangle];
            
            
//            NSLog(@"actionstr==%@----indexstr==%@----timestr==%@*----powerstr==%@----anglestr==%@",actionstr,indexstr,timestr,powerstr,anglestr);
//            NSLog(@"newactionstr==%@----newindexstr==%@----newtimestr==%@*----newpowerstr==%@----newanglestr==%@",newactionstr,newindexstr,newtimestr,newpowerstr,newanglestr);

            
            
        }
    }
}

#pragma mark - 解析蓝牙二进制数据(str : 二进制字符串)
-(void)dealData: (NSString*) str fortyep: (modeltyep) tyep {
    
    if (tyep == tyepaction) {
        NSString * actionstr = [str substringWithRange:NSMakeRange(12, 4)];
        self.action.text = [NSString stringWithFormat:@"动作 %d",(int)strtoul([actionstr UTF8String], 0, 2)];
        NSString * speedstr = [str substringWithRange:NSMakeRange(2, 10)];
        self.speed.text = [NSString stringWithFormat:@"速度 %d",(int)strtoul([speedstr UTF8String], 0, 2)];
        NSString * sync_flagstr = [str substringWithRange:NSMakeRange(2, 1)];
        self.sync_flag.text = [NSString stringWithFormat:@"是否同步 %d",(int)strtoul([sync_flagstr UTF8String], 0, 2)];
    }else if (tyep == tyeptime){
        NSString * secstr = [str substringWithRange:NSMakeRange(1, 6)];
        self.sec.text = [NSString stringWithFormat:@"%d秒",(int)strtoul([secstr UTF8String], 0, 2)];
        
        NSString * minstr = [str substringWithRange:NSMakeRange(6, 6)];
        self.min.text = [NSString stringWithFormat:@"%d分",(int)strtoul([minstr UTF8String], 0, 2)];
        
        NSString * hourstr = [str substringWithRange:NSMakeRange(12, 5)];
        self.hour.text = [NSString stringWithFormat:@"%d小时",(int)strtoul([hourstr UTF8String], 0, 2)];
        
        NSString * daystr = [str substringWithRange:NSMakeRange(17, 5)];
        self.day.text = [NSString stringWithFormat:@"%d日",(int)strtoul([daystr UTF8String], 0, 2)];
        
        NSString * monthstr = [str substringWithRange:NSMakeRange(22, 4)];
        self.month.text = [NSString stringWithFormat:@"%d月",(int)strtoul([monthstr UTF8String], 0, 2)];
        
        NSString * yearstr = [str substringWithRange:NSMakeRange(26, 6)];
        self.year.text = [NSString stringWithFormat:@"%d年",(int)strtoul([yearstr UTF8String], 0, 2)];
        
        
    }else if (tyep == tyepangle){
        NSString * vertical_angle_direction = [str substringWithRange:NSMakeRange(1, 2)];
        self.vertical_angle_direction.text = [NSString stringWithFormat:@"垂直角度的方向 %d",(int)strtoul([vertical_angle_direction UTF8String], 0, 2)];
        
        NSString * vertical_angle = [str substringWithRange:NSMakeRange(2, 9)];
        self.vertical_angle.text = [NSString stringWithFormat:@"垂直角度 %d",(int)strtoul([vertical_angle UTF8String], 0, 2)];
        NSString * inning_val = [str substringWithRange:NSMakeRange(11, 10)];
        self.inning_val.text = [NSString stringWithFormat:@"局值 %d",(int)strtoul([inning_val UTF8String], 0, 2)];
        NSString * angle_direction = [str substringWithRange:NSMakeRange(21, 2)];
        self.angle_direction.text = [NSString stringWithFormat:@"角度方向 %d",(int)strtoul([angle_direction UTF8String], 0, 2)];
        NSString * angle = [str substringWithRange:NSMakeRange(23, 9)];
        self.angle.text = [NSString stringWithFormat:@"角度 %d",(int)strtoul([angle UTF8String], 0, 2)];
        
    }
    
    
    
}
#pragma mark - 处理带参数的命令,拼接获得字符串,参数使用字符串的形式传递,如果不带参数字符串传nil,返回值data就是传递给蓝牙的命令
-(NSData*)setupdata:(NSString * ) str fororder: (int) order{
    //别名NSdata
    NSData* strdata = [str dataUsingEncoding:NSUTF8StringEncoding];
    //命令data
    NSData * orderdata = [NSData dataWithBytes:&order length:1];//1个字节
    //长度data
    NSUInteger length = strdata.length;
    NSData * lengthdata = [NSData dataWithBytes:&length length:1];//1个字节
    //拼接data(最终使用的data)
    NSMutableData * newdata = [[NSMutableData alloc] init];
    [newdata appendData:orderdata];
    [newdata appendData:lengthdata];
    [newdata appendData:strdata];
    //字节数组
    Byte *testByte = (Byte *)[newdata bytes];
    //和用来验证CRC
    int index = 0;
    for(int i=0;i<([newdata length]);i++){
        index += testByte[i];
    }
    int crc = index % 256;
    //CRC的data
    NSData *  crcdata = [NSData dataWithBytes:&crc length:2];//2个字节
    [newdata appendData:crcdata];
    //    NSLog(@"%@--%@--%@",crcdata,strdata,newdata);
    return newdata;
    
}

#pragma mark -拼接处理字符串 U16
-(NSString * )handleStringU16:(NSString*) str {
    NSString * str1=[str substringWithRange:NSMakeRange(0, 2)];
    NSString * str2 = [str substringWithRange:NSMakeRange(2, 2)];
    NSString * newstr = [str2 stringByAppendingString:str1];
    return newstr;
}
#pragma mark -拼接处理字符串 U32
-(NSString * )handleStringU32:(NSString*)str {
    NSString * str1=[str substringWithRange:NSMakeRange(0, 2)];  //10
    NSString * str2 = [str substringWithRange:NSMakeRange(2, 2)];//3d
    NSString * str3 = [str substringWithRange:NSMakeRange(4, 2)];//a3
    NSString * str4 = [str substringWithRange:NSMakeRange(6, 2)];//04
    NSString * newstr = [str4 stringByAppendingString:str3];
    newstr = [newstr stringByAppendingString:str2];
    newstr = [newstr stringByAppendingString:str1];
    return newstr;
}
#pragma mark -把一个16进制的字符串转化为二进制的字符串的方法
- (NSString *)getBinaryByhex:(NSString *) hex
{
    NSMutableDictionary  *hexDic = [[NSMutableDictionary alloc] init];
    hexDic = [[NSMutableDictionary alloc] initWithCapacity:16];
    [hexDic setObject:@"0000" forKey:@"0"];
    [hexDic setObject:@"0001" forKey:@"1"];
    [hexDic setObject:@"0010" forKey:@"2"];
    [hexDic setObject:@"0011" forKey:@"3"];
    [hexDic setObject:@"0100" forKey:@"4"];
    [hexDic setObject:@"0101" forKey:@"5"];
    [hexDic setObject:@"0110" forKey:@"6"];
    [hexDic setObject:@"0111" forKey:@"7"];
    [hexDic setObject:@"1000" forKey:@"8"];
    [hexDic setObject:@"1001" forKey:@"9"];
    [hexDic setObject:@"1010" forKey:@"a"];
    [hexDic setObject:@"1011" forKey:@"b"];
    [hexDic setObject:@"1100" forKey:@"c"];
    [hexDic setObject:@"1101" forKey:@"d"];
    [hexDic setObject:@"1110" forKey:@"e"];
    [hexDic setObject:@"1111" forKey:@"f"];
    
    NSMutableString *binaryString=[[NSMutableString alloc] init];
    if (hex.length) {
        for (int i=0; i<[hex length]; i++) {
            NSRange rage;
            rage.length = 1;
            rage.location = i;
            NSString *key = [hex substringWithRange:rage];
            [binaryString appendString:hexDic[key]];
        }
    }
    return binaryString;
}




#pragma mark 把nsdata转化为16进制的一个字符串方法
- (NSString *)hexStringFromString:(NSData *)data{
    //    NSData *myD = [string dataUsingEncoding:NSUTF8StringEncoding];
    Byte *bytes = (Byte *)[data bytes];
    //下面是Byte 转换为16进制。
    NSString *hexStr=@"";
    for(int i=0;i<[data length];i++)
        
    {
        NSString *newHexStr = [NSString stringWithFormat:@"%x",bytes[i]&0xff];///16进制数
        
        if([newHexStr length]==1)
            
            hexStr = [NSString stringWithFormat:@"%@0%@",hexStr,newHexStr];
        
        else
            
            hexStr = [NSString stringWithFormat:@"%@%@",hexStr,newHexStr];
    }
    return hexStr;
}

#pragma mark tableView的代理方法
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    
    return self.blueItems.count;
}
static NSString * ID= @"cell";
-(UITableViewCell * )tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    
    UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:ID];
    if (cell == nil) {
        cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID];
    }
    cell.textLabel.text = self.blueItems[indexPath.row];
    return cell;
    
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    self.mainperipheral = self.currPeripherals[indexPath.row];
    //2 扫描、连接到 peripher 设备
    self.baby.having(self.mainperipheral).connectToPeripherals().begin();
    //设置peripheral 然后读取services,然后读取characteristics名称和值和属性，获取characteristics对应的description的名称和值
    self.baby.having(self.mainperipheral).connectToPeripherals().discoverServices().discoverCharacteristics()
    .readValueForCharacteristic().discoverDescriptorsForCharacteristic().readValueForDescriptors().begin();
}


@end
